package com.wkbb.common.base;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wkbb.common.constants.Constants;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.RedisKeyConstant;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.OrganizationDto;
import com.wkbb.common.dto.basic.RoleTypeDto;
import com.wkbb.common.dto.basic.RoleTypeJsonDto;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.enums.SysRoleTypeEnum;
import com.wkbb.common.redis.RedisTemplateUtil;
import com.wkbb.common.redis.UserRedisTemplateUtil;
import com.wkbb.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
@Slf4j
public class BaseController {

    @Autowired
    private UserRedisTemplateUtil redisTemplateUtil;
        
    /**
     * 微信端根据OPENID获取当前用户信息
     */
    protected UserDto getUserByUnion() {

        String userTokenRedisKey = getUserTokenRedisKey();
        if (StringUtil.isEmpty(userTokenRedisKey)) {
            return null;
        }

        String userJsonStr = redisTemplateUtil.getJSON(userTokenRedisKey);
        log.debug("********BaseController.getUserByUnion********userTokenRedisKey:{} userJsonStr:{}",userTokenRedisKey,userJsonStr);
        if (StringUtil.isEmpty(userJsonStr)) {
            return null;
        }

        UserDto user = JSONObject.parseObject(userJsonStr, UserDto.class);

        return user;
    }

    /**
     * 微信端根据OPENID获取当前用户ID
     */
    protected Long getUserIdByUnion() {

        String userTokenRedisKey = getUserTokenRedisKey();
        String userJsonStr = redisTemplateUtil.getJSON(userTokenRedisKey);
        log.debug("********BaseController.getUserIdByUnion********userJsonStr:{}",userJsonStr);
        if (StringUtil.isEmpty(userJsonStr)) {
            return null;
        }

        UserDto user = JSONObject.parseObject(userJsonStr, UserDto.class);

        return user.getId();
    }

    protected UserDto getUserByUnionAndAccount(Long accountId) {

        log.debug("******getUserByUnionAndAccount*****accountId:{}****",accountId);
        UserDto userDto = null;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        log.debug("******getUserByUnionAndAccount*****token:{}****",token);
        if(token.indexOf(Constants.SEPARATOR_CHAR)>-1 || token.indexOf(Constants.SEPARATOR_CHAR_2)>-1)
        {
            userDto = getUserByUnion();
        }
        else
        {
            String unionId = token;
            String userTokenRedisKey = String.format(RedisKeyConstant.WKBB_BASIC_USER_FRONT + RedisKeyConstant.WKBB_BASIC_USER_FRONT_ACCOUNT_UNIONID, accountId, unionId);
            String userJsonStr = redisTemplateUtil.getJSON(userTokenRedisKey);
            if (!StringUtil.isEmpty(userJsonStr)) {
                userDto = JSONObject.parseObject(userJsonStr, UserDto.class);

                String userAccountRedisKey = String.format(RedisKeyConstant.WKBB_BASIC_USER_FRONT + RedisKeyConstant.WKBB_BASIC_USER_FRONT_TOKEN_ACCOUNT, unionId);
                redisTemplateUtil.set(userAccountRedisKey,accountId);
            }
        }

        return userDto;
    }

    private String getUserTokenRedisKey()
    {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String token = request.getHeader("token");
        log.debug("********BaseController.getUserTokenRedisKey********token:{}",token);
        if (StringUtil.isEmpty(token)||Constants.SEPARATOR_CHAR.equals(token)||Constants.SEPARATOR_CHAR_2.equals(token)) {
            return null;
        }

        //解析token
        String accountId = null;
        String unionId = null;
        if(token.indexOf(Constants.SEPARATOR_CHAR)>-1)
        {
            String[] tokenArr = token.split(Constants.SEPARATOR_CHAR);
            unionId = tokenArr[0];
            if(tokenArr.length>1) {
                accountId = tokenArr[1];
            }
        }
        else if(token.indexOf(Constants.SEPARATOR_CHAR_2)>-1)
        {
            String[] tokenArr = token.split(Constants.SEPARATOR_CHAR_2);
            unionId = tokenArr[0];
            if(tokenArr.length>1) {
                accountId = tokenArr[1];
            }
        }
        else
        {
            unionId = token;
        }

        log.debug("********BaseController.getUserTokenRedisKey********accountId:{},token:{}",accountId,token);

        //如果accountId为空，尝试取缓存里的，处理小程序丢失accountId问题
        if(StringUtils.isEmpty(accountId))
        {
            String userAccountRedisKey = String.format(RedisKeyConstant.WKBB_BASIC_USER_FRONT + RedisKeyConstant.WKBB_BASIC_USER_FRONT_TOKEN_ACCOUNT, unionId);
            Object accountIdObj = redisTemplateUtil.get(userAccountRedisKey);
            if(null!=accountIdObj)
            {
                accountId = accountIdObj.toString();
            }
        }

        log.debug("********BaseController.getUserTokenRedisKey********redis accountId:{}",accountId);

        String userTokenRedisKey = null;
        if(StringUtils.isEmpty(accountId))
        {
            userTokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_FRONT + RedisKeyConstant.WKBB_BASIC_USER_FRONT_UNIONID + unionId;
        }
        else {
            //兼容老版本（不支持跨集团）
            userTokenRedisKey = String.format(RedisKeyConstant.WKBB_BASIC_USER_FRONT + RedisKeyConstant.WKBB_BASIC_USER_FRONT_ACCOUNT_UNIONID, accountId, unionId);
        }

        log.debug("********BaseController.getUserTokenRedisKey********userTokenRedisKey:{}",userTokenRedisKey);

        return userTokenRedisKey;
    }

    //是否为超管
    protected boolean isSuperAdmin(UserDto userDto){
        return userDto.getOrgId() == 1;
    }

    /**
     * 后台根据登录信息获取当前用户信息
     */
    protected UserDto getUserByLogin(){

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String token = request.getHeader("token");
        // 尝试不同大小写的请求头名称
        if (StringUtil.isEmpty(token)) {
            token = request.getHeader("Token");
        }
        if (StringUtil.isEmpty(token)) {
            token = request.getHeader("TOKEN");
        }
        log.debug("********BaseController.getUserByLogin********token:{}",token);
        if (StringUtil.isEmpty(token)) {
            return null;
        }

        String userJsonStr = redisTemplateUtil.getJSON(RedisKeyConstant.WKBB_BASIC_USER_BACK + RedisKeyConstant.WKBB_BASIC_USER_BACK_TOKEN + token);
        log.debug("********BaseController.getUserByLogin********userJsonStr:{}",userJsonStr);
        if (StringUtil.isEmpty(userJsonStr)) {
            return null;
        }

        //UserDto user = new UserDto();//JSONObject.parseObject(userJsonStr, UserDto.class);
		//user.setName("test");
        UserDto userDto =  JSONObject.parseObject(userJsonStr, UserDto.class);
        Long orgId = ((JSONArray) userDto.getRoleType()).getJSONObject(0).getLong("orgId");
        userDto.setOrgId(orgId);
        return userDto;

    }

    protected UserDto getRouteUserByUnion()
    {
        String tokenRedisKey = RedisKeyConstant.WKBB_BASIC_USER_ROUTE + RedisKeyConstant.WKBB_BASIC_USER_ROUTE_TOKEN_UNIONID;//路由模式
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        String userTokenRedisKey = String.format(tokenRedisKey, token);
//        String userJsonStr = redisTemplateUtil.getJSON(userTokenRedisKey);
//        if (!StringUtil.isEmpty(userJsonStr)) {
//            userDto = JsonUtil.jsonToClass(userJsonStr,UserDto.class);
//        }
        return (UserDto)redisTemplateUtil.get(userTokenRedisKey);
    }


    /**
     * 后台根据登录信息获取当前用户信息
     */
    protected UserDto getUserByLogin(String token) {
        log.debug("********BaseController.getUserByLogin********token:{}",token);
        if (StringUtil.isEmpty(token)) {
            return null;
        }
        String userJsonStr = redisTemplateUtil.getJSON(RedisKeyConstant.WKBB_BASIC_USER_BACK + RedisKeyConstant.WKBB_BASIC_USER_BACK_TOKEN + token);
        log.debug("********BaseController.getUserByLogin********userJsonStr:{}",userJsonStr);
        if (StringUtil.isEmpty(userJsonStr)) {
            return null;
        }
        return JSONObject.parseObject(userJsonStr, UserDto.class);

    }

    /**
     * 后台根据登录信息获取当前用户ID
     */
    protected Long getUserIdByLogin() {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String token = request.getHeader("token");
        log.debug("********BaseController.getUserIdByLogin********token:{}",token);
        if (StringUtil.isEmpty(token)) {
            return null;
        }

        String userJsonStr = redisTemplateUtil.getJSON(RedisKeyConstant.WKBB_BASIC_USER_BACK + RedisKeyConstant.WKBB_BASIC_USER_BACK_TOKEN + token);
        log.debug("********BaseController.getUserIdByLogin********userJsonStr:{}",userJsonStr);
        if (StringUtil.isEmpty(userJsonStr)) {
            return null;
        }

        UserDto user = JSONObject.parseObject(userJsonStr, UserDto.class);

        return user.getId();
    }

    /**
     * 获取用户组织ID
     * */
    protected OrganizationDto getOrgByUser(UserDto userDto)
    {

        Long orgId = ((JSONArray) userDto.getRoleType()).getJSONObject(0).getLong("orgId");
        String orgName = ((JSONArray) userDto.getRoleType()).getJSONObject(0).getString("orgName");
        Integer orgType =((JSONArray) userDto.getRoleType()).getJSONObject(0).getInteger("orgType");

        OrganizationDto organizationDto = new OrganizationDto();
        organizationDto.setId(orgId);
        organizationDto.setName(orgName);
        organizationDto.setOrgType(orgType);

        return organizationDto;
    }

    /**
     * 获取匹配用户组织
     * */
    protected OrganizationDto getOrgByUser(UserDto userDto,Long realOrgId)
    {
        JSONArray userRoleTypeJsonArray = (JSONArray) userDto.getRoleType();

        //如果数据格式有问题，则抛出
        if(userRoleTypeJsonArray.size()==0)
        {
            return null;
        }

        for (int i = 0; i < userRoleTypeJsonArray.size(); i++) {
            JSONObject roleTypeObject = userRoleTypeJsonArray.getJSONObject(i);
            RoleTypeJsonDto roleTypeJsonDto = JSONObject.parseObject(roleTypeObject.toJSONString(),RoleTypeJsonDto.class);
            if(null!=roleTypeJsonDto) {
                Long orgId = roleTypeJsonDto.getOrgId();
                String orgName = roleTypeJsonDto.getOrgName();
                Integer orgType = roleTypeJsonDto.getOrgType();

                //比较，匹配到
                if(realOrgId.equals(orgId))
                {
                    OrganizationDto organizationDto = new OrganizationDto();
                    organizationDto.setId(orgId);
                    organizationDto.setName(orgName);
                    organizationDto.setOrgType(orgType);
                    return organizationDto;
                }
            }
        }
        return null;
    }

    /**
     * 获取用户组织类型
     * */
    protected Integer getOrgTypeByUser(UserDto userDto)
    {
        return ((JSONArray) userDto.getRoleType()).getJSONObject(0).getInteger("orgType");
    }

    /**
     * 获取用户角色类型
     * */
    protected Integer getRoleTypeByUser(UserDto userDto)
    {
        // 验证token是否经过篡改，并防止token伪造
        JSONArray userRoleTypeJsonArray = (JSONArray) userDto.getRoleType();

        //如果数据格式有问题，则抛出
        if(userRoleTypeJsonArray.size()==0)
        {
            return null;
        }

        //校验
        Integer roleType = SysRoleTypeEnum.EMPLOYEE.getValue();
        for (int i = 0; i < userRoleTypeJsonArray.size(); i++) {
            JSONObject roleTypeObject = userRoleTypeJsonArray.getJSONObject(i);

            RoleTypeJsonDto roleTypeJsonDto = JSONObject.parseObject(roleTypeObject.toJSONString(),RoleTypeJsonDto.class);
            if(null!=roleTypeJsonDto) {
                List<RoleTypeDto> roleTypes = roleTypeJsonDto.getRoleTypes();
                for (RoleTypeDto roleTypeDto : roleTypes) {

                    //比较，匹配到，则说明token有效
                    if(SysRoleTypeEnum.SUPER_ADMIN.getValue()==roleTypeDto.getRoleType())
                    {
                        roleType = SysRoleTypeEnum.SUPER_ADMIN.getValue();
                        break;
                    }

                    roleType = roleTypeDto.getRoleType().intValue();
                }
            }

        }

        return roleType;
    }

    /**
     * 获取用户是否是超管
     * */
    protected Boolean getUserIsSuper(UserDto userDto)
    {
        Integer roleType = this.getRoleTypeByUser(userDto);

        return SysRoleTypeEnum.SUPER_ADMIN.getValue() == roleType;
    }


    /**
     * 获取当前用户角色类型
     * @param userDto 用户信息
     * @return 如果为超管和管理员则返回null 为职员返回userId
     */
    public Long getRoleUserId(UserDto userDto){
        Integer roleId = getRoleTypeByUser(userDto);
        boolean bl = roleId != null && (SysRoleTypeEnum.SUPER_ADMIN.getValue() == roleId || SysRoleTypeEnum.ADMIN.getValue() == roleId);
        if(bl){
            return null;
        }else{
            return userDto.getId();
        }
    }

    /**
     * 基础返回
     * @param b
     * @return
     */
    protected ResultDTO<Boolean> getResult(boolean b){
        ResultDTO<Boolean> resultDTO =  new ResultDTO<>(b ? ErrorCode.SUCCESS : ErrorCode.SYSTEM_ERROR);
        resultDTO.setData(b);
        return resultDTO;
    }
}
